package com.zhihaoliang.coroutine.buss.flow.func

import com.zhihaoliang.coroutine.util.log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch

/**
 * @author 支豪亮
 * @date 2022/10/24 15:11
 * @des 流的一些操作
 *
 * map : 转化器 可以接受 suspend 方法 以及 操作
 * transform ： 转化器 接受 FlowCollector
 * filter ：过滤器
 * take : 截取长度
 * toList ： 转换成 List
 * toSet ： 转化为 Set
 * first ： 获取第一个数据
 * reduce and fold 的区别 ：fold 有初始值
 */
object FlowOperators {

    fun onTransform(mainScope: CoroutineScope) = mainScope.launch {
        (1..3).asFlow() // a flow of requests
            .map {
                performRequest(it)
            }
            .transform {
                emit(it)
                emit("Hello emit $it")
            }
            .filter { it.length > 2 }
            .take(5)
            .collect { response -> log(response) }

        for (item in (1..3).asFlow().toList()){
            log("toList $item")
        }

        for (item in (1..3).asFlow().toSet()){
            log("toSet $item")
        }

        log((1..3).asFlow().first())
    }

    fun onReduce(mainScope: CoroutineScope) = mainScope.launch{
        val sum = (1..5).asFlow()
            .map { it * it } // squares of numbers from 1 to 5
            .reduce { a, b -> a + b } // sum them (terminal operator)
        log(sum)

        val sum1 = (1..5).asFlow()
            .map { it * it } // squares of numbers from 1 to 5
            .fold(100) { a, b -> a + b } // sum them (terminal operator)
        log(sum1)
    }

    suspend fun performRequest(request: Int): String {
        delay(1000) // imitate long-running asynchronous work
        return "response $request"
    }

}